<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>browser 路由</title>
</head>

<body>
  <div id="root"></div>
  <!-- 
  Browser 路由是利用 html5 中的 history API 实现路由切换
  window.history 是一个 BOM 对象 提供了与浏览器历史记录交互的方法和属性
  history 提供了很多的方法和属性 但由于安全原因 大多数浏览器都限制了 history 的能力
  比如不能查看用户的历史记录 只能知道有多少条 但不知道它们是什么

  history.length 返回浏览器历史列表中的URL数量
  history.back() 与点击浏览器中的回退按钮效果相同
  history.forward() 与点击浏览器中的前进按钮效果相同
  history.go(n) 其中 n 是一个整数 表示跳转到相当于当前页面的位置
    history.go(-1) 等价于 history.back()
    history.go(1) 等价于 history.forward()

  history.pushState(state, title, url) 向历史栈中添加一个新的条目
    state 与新历史条目关联的状态对象 可以为 null
    title 目前被所有的浏览器忽略 可留空字符串
    url 新的相对或绝对地址 
  history.replaceState(state, title, url) 替换当前历史记录 不会在历史栈中新增一个条目
    state 与新历史条目关联的状态对象 可以为 null
    title 目前被所有的浏览器忽略 可留空字符串
    url 新的相对或绝对地址 


  -->
  <script>
    const historyObj = window.history
    const root = document.getElementById('root')
    function updateContent(content) {
      root.innerHTML = content
    }
    // 用户点击浏览器 前进 、 后退 、 history.back history.forward history.go 会触发
    // history.pushState history.replaceState 不会触发 popstate 事件
    window.addEventListener('popstate', (event) => { // 当路径切换时
      updateContent(window.location.pathname)
    })
      ; (function (historyObj) {
        let oldPushState = history.pushState
        // 重写原生 history.pushState 方法
        history.pushState = function (state, title, url) {
          let result = oldPushState.apply(historyObj, arguments) // 先执行原生的 pushState 方法
          updateContent(url) // 然后再执行用户自己的逻辑
          return result // 返回原生 pushState 调用后的返回值
        }
        let oldReplaceState = historyObj.replaceState
        // 重写原生 history.replaceState
        history.replaceState = function(state, title, url){
          let result = oldReplaceState.apply(historyObj, arguments) // 先执行原生的 replaceState 方法
          updateContent(url) // 然后再执行用户自己的逻辑
          return result
        }
      })(historyObj);
    setTimeout(() => {
      historyObj.pushState({ page: 1 }, '', '/page1')
    }, 1000)
    setTimeout(() => {
      historyObj.pushState({ page: 2 }, '', '/page2')
    }, 2000)
    setTimeout(() => {
      historyObj.pushState({ page: 3 }, '', '/page3')
    }, 3000)
    setTimeout(() => {
      historyObj.back()
    }, 4000)
    setTimeout(() => {
      historyObj.pushState({ page: 4 }, '', '/page4')
    }, 5000)
    setTimeout(() => {
      historyObj.go(1)
    }, 1000 * 6)

  </script>
</body>

</html>
